<template>
  <ych-modal
    :fullscreen="true"
    :title="title"
    :visible="visible"
    :confirmLoading="spinning > 0"
    @ok="handleOk"
    @cancel="handleCancel"
    :cancelText="$t('m.common.button.close')">
    <a-spin :spinning="spinning > 0">
      <!-- 主表单区域 -->
      <a-form :form="form">
        <a-row>
          <a-col :span="7">
            <a-form-item :label="$t('m.eform.apptable.entity.tableName')" :labelCol="labelCol" :wrapperCol="wrapperCol" style="margin-bottom:0;">
              <a-input v-decorator="[ 'tableName', validatorRules.tableName]" placeholder=""
                       :disabled="disabledRules.tableName"></a-input>
            </a-form-item>
          </a-col>
          <a-col :span="7">
            <a-form-item :label="$t('m.eform.apptable.entity.tableDesc')" :labelCol="labelCol" :wrapperCol="wrapperCol" style="margin-bottom:0;">
              <a-input v-decorator="[ 'tableDesc', validatorRules.tableDesc]" placeholder=""></a-input>
            </a-form-item>
          </a-col>
          <a-col :span="6">
            <a-form-item :label="$t('m.eform.apptable.entity.dsName')" :labelCol="labelCol" :wrapperCol="wrapperCol" style="margin-bottom:0;">
              <select-ds v-decorator="[ 'dsCode', validatorRules.dsCode]" placeholder=""
                         :disabled="disabledRules.dsCode" :allow-clear="false"></select-ds>
            </a-form-item>
          </a-col>
          <a-col :span="4">
            <a-form-item :label="$t('m.common.label.sort')" :labelCol="labelCol2" :wrapperCol="wrapperCol2" style="margin-bottom:0;">
              <a-input-number v-decorator="[ 'orderNum', validatorRules.orderNum]"></a-input-number>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>

      <!-- 子表单区域 -->
      <a-tabs v-model="activeKey">
        <a-tab-pane :tab="$t('m.eform.apptable.other.db_properties')" :key="refKeys[0]" :forceRender="true">

          <vxe-toolbar>
            <template #buttons>
              <a-button type="primary" icon="plus" @click="insertRow('xTable', dataSource, initData, 'colCode')">{{ $t('m.common.button.add') }}</a-button>
              <span class="action-button-gap"></span>
              <a-button type="default" icon="minus" @click="deleteRow">{{ $t('m.common.button.delete') }}</a-button>
              <span class="action-button-gap"></span>
              <a-button type="default" icon="plus" @click="addSystemField">{{ $t('m.common.button.addSystemField') }}</a-button>
            </template>
          </vxe-toolbar>

          <vxe-table
            header-align="center"
            border
            :scroll-y="{enabled: false}"
            ref="xTable"
            class="sortable-row-vxe"
            show-header-overflow
            show-overflow
            :height="height"
            :edit-rules="validRules"
            :row-config="{isHover: true, useKey: true, keyField: 'id'}"
            :edit-config="{trigger: 'click', mode: 'cell', activeMethod: activeRowMethod}"
            :data="dataSource">
            <vxe-column width="60" align="center">
              <template #default>
                <span class="drag-btn">
                  <i class="vxe-icon-num-list"></i>
                </span>
              </template>
            </vxe-column>
            <vxe-column type="checkbox" width="50" align="center"></vxe-column>
            <vxe-column type="seq" :title="$t('m.common.label.number')" width="50" align="center"></vxe-column>
            <vxe-column field="colCode" :title="$t('m.eform.apptable.entity.colCode')" :edit-render="{name: 'input'}" :min-width="150"></vxe-column>
            <vxe-column field="colName" :title="$t('m.eform.apptable.entity.colName')" :edit-render="{name: 'input'}" :min-width="150"></vxe-column>
            <vxe-column field="colType" :title="$t('m.eform.apptable.entity.colType')"
                        :edit-render="{name: 'select', options: colType, events: {change: changeColType}}"
                        :min-width="120" align="center"></vxe-column>
            <vxe-column field="colLength" :title="$t('m.eform.apptable.entity.colLength')"
                        :edit-render="{name: 'input', attrs: {type: 'number'}}" :min-width="110" align="center"></vxe-column>
            <vxe-column field="colPointLength" :title="$t('m.eform.apptable.entity.colPointLength')"
                        :edit-render="{name: 'input', attrs: {type: 'number'}}" :min-width="110" align="center"></vxe-column>
            <vxe-column field="isKey" :title="$t('m.eform.apptable.entity.isKey')" :min-width="80" align="center">
              <template #default="{ row }">
                <vxe-checkbox v-model="row.isKey" checked-value="Y" unchecked-value="N" disabled></vxe-checkbox>
              </template>
            </vxe-column>
            <vxe-column field="isNull" :title="$t('m.eform.apptable.entity.isNull')" :edit-render="{}" :min-width="110" align="center">
              <template #header="{ column, columnIndex }">
                <vxe-checkbox v-model="isNullCheckAll" checked-value="Y" unchecked-value="N" @change="changeAllIsNull($event)"
                              >{{$t('m.eform.apptable.entity.isNull')}}</vxe-checkbox>
              </template>
              <template #default="{ row }">
                <vxe-checkbox v-model="row.isNull" checked-value="Y" unchecked-value="N"
                              :disabled="row.isDefault === 'Y'" @change="changeIsNull(row, $event)"></vxe-checkbox>
              </template>
              <template #edit="{ row }">
                <vxe-checkbox v-model="row.isNull" checked-value="Y" unchecked-value="N"
                              :disabled="row.isDefault === 'Y'" @change="changeIsNull(row, $event)"></vxe-checkbox>
              </template>
            </vxe-column>
            <vxe-column field="colDefaultVal" :title="$t('m.eform.apptable.entity.colDefaultVal')" :edit-render="{name: 'input'}" :min-width="120"></vxe-column>
          </vxe-table>

        </a-tab-pane>
        <a-tab-pane :tab="$t('m.eform.apptable.other.page_properties')" :key="refKeys[1]" :forceRender="true">

          <vxe-table
            header-align="center"
            border
            :scroll-y="{enabled: false}"
            show-header-overflow
            show-overflow
            :height="height2"
            :row-config="{isHover: true, keyField: 'id'}"
            :edit-config="{trigger: 'click', mode: 'cell'}"
            :data="dataSource">
            <vxe-column type="seq" :title="$t('m.common.label.number')" width="50" align="center"></vxe-column>
            <vxe-column field="colName" :title="$t('m.eform.apptable.entity.colName')" :min-width="150"></vxe-column>
            <vxe-column field="colType" :title="$t('m.eform.apptable.entity.colType')" :min-width="120" align="center" :formatter="formatterColType"></vxe-column>
            <vxe-column field="showType" :title="$t('m.eform.apptable.entity.showType')"
                        :edit-render="{name: 'select', options: showType}" :min-width="120" align="center"></vxe-column>
            <vxe-column field="showConfig" :title="$t('m.eform.apptable.entity.showConfig')" :edit-render="{}" :min-width="130" align="center">
              <template #default="{ row }">
                <a-badge
                  :dot="!!row.showConfig && noShowConfig.indexOf(row.showType) === -1">
                  <a-button
                    :disabled="noShowConfig.indexOf(row.showType) !== -1"
                    type="link" size="small" @click="showConfigButton(row)">{{ $t('m.common.button.config') }}
                  </a-button>
                </a-badge>
              </template>
              <template #edit="{ row }">
                <a-badge
                  :dot="!!row.showConfig && noShowConfig.indexOf(row.showType) === -1">
                  <a-button
                    :disabled="noShowConfig.indexOf(row.showType) !== -1"
                    type="link" size="small" @click="showConfigButton(row)">{{ $t('m.common.button.config') }}
                  </a-button>
                </a-badge>
              </template>
            </vxe-column>
            <vxe-column field="dataConfig" :title="$t('m.eform.apptable.entity.dataConfig')" :edit-render="{}" :min-width="130" align="center">
              <template #default="{ row }">
                <a-badge :dot="!!row.dataConfig">
                  <a-button type="link" size="small" @click="dataConfigButton(row)">{{ $t('m.common.button.config') }}</a-button>
                </a-badge>
              </template>
              <template #edit="{ row }">
                <a-badge :dot="!!row.dataConfig">
                  <a-button type="link" size="small" @click="dataConfigButton(row)">{{ $t('m.common.button.config') }}</a-button>
                </a-badge>
              </template>
            </vxe-column>
            <vxe-column field="validRule" :title="$t('m.eform.apptable.entity.validRule')" :formatter="formatterValidRule" :edit-render="{}"
                        :min-width="150">
              <template #edit="{ row }">
                <ych-vxe-multiple-select v-model="row.validRule" clearable :options="validRule">
                </ych-vxe-multiple-select>
              </template>
            </vxe-column>
            <vxe-column field="isRequired" :title="$t('m.eform.apptable.entity.isRequired')" :edit-render="{}" :min-width="80" align="center">
              <template #default="{ row }">
                <vxe-checkbox v-model="row.isRequired" checked-value="Y" unchecked-value="N"></vxe-checkbox>
              </template>
              <template #edit="{ row }">
                <vxe-checkbox v-model="row.isRequired" checked-value="Y" unchecked-value="N"></vxe-checkbox>
              </template>
            </vxe-column>
          </vxe-table>

        </a-tab-pane>
      </a-tabs>

    </a-spin>

    <form-show-config-dialog ref="formShowConfigDialog" @selectFinished="showConfigOk" :is-table="true"
                             @saveToDataConfig="saveToDataConfig"
                             :tableColList="dataSource" :groupId="groupId"></form-show-config-dialog>

    <data-config-dialog ref="dataConfigDialog" @selectFinished="dataConfigOk" :is-table="true"
                        :groupId="groupId"></data-config-dialog>
    <select-system-field ref="selectSystemField" @selectSystemFieldOk="selectSystemFieldOk"></select-system-field>

  </ych-modal>
</template>

<script>

import {getAction} from '@/api/manage'
import {EFormConstant} from '../EFormConstant'
import SelectDs from '../select/tag/SelectDs'
import FormShowConfigDialog from './actAppTable/FormShowConfigDialog'
import DataConfigDialog from './actAppView/DataConfigDialog'
import YchConstant from "@/api/YchConstant";
import YchVxeMultipleSelect from '../../../components/ych/YchVxeMultipleSelect'
import {randomString} from "../../../utils/util";
import {YchVxeTableMixin} from '../../../mixins/YchVxeTableMixin'
import pinyin from 'js-pinyin'
import SelectSystemField from './actAppTable/SelectSystemField'
import config from '@/settings'

export default {
  name: 'ActAppTableModal',
  mixins: [YchVxeTableMixin],
  components: {
    SelectDs,
    FormShowConfigDialog,
    DataConfigDialog,
    YchVxeMultipleSelect,
    SelectSystemField
  },
  props: {
    groupId: {
      type: String,
      required: true
    },
  },
  data() {
    const colLengthValid = ({cellValue, row}) => {
      let max
      if (!row.colType || row.colType === 'varchar') {
        max = config.tableColMaxLength || 4000
      } else if (row.colType === 'number') {
        max = 65
      } else {
        return
      }
      const message = this.$t('m.eform.formDesign.label.field_max_length_msg', [max])
      let num = Number(cellValue)
      if (isNaN(num) || num < 1 || num > max) {
        return new Error(message)
      }
    }
    const colPointLengthValid = ({cellValue, row}) => {
      let colLength = Number(row.colLength);
      if (isNaN(colLength)) {
        colLength = 0;
      }
      let num = Number(cellValue)
      if (isNaN(num) || num < 0 || num > 30 || num > colLength) {
        return new Error(this.$t('m.eform.formDesign.label.xiao-shu-dian-wei-bi-xu-wei-030-zhi-jian-de-shu-zi'))
      }
      if (num > colLength) {
        return new Error(this.$t('m.eform.formDesign.label.xiao-shu-dian-wei-bu-neng-da-yu-zi-duan-chang-du'))
      }
    }
    const colCodeValid = ({cellValue, row}) => {
      if (cellValue) {
        const uniqueRow = this.dataSource.find(item => item.colCode && item.colCode.toLowerCase() === cellValue.toLowerCase() && item.id !== row.id)
        if (uniqueRow) {
          return new Error(this.$t('m.eform.formDesign.label.zi-duan-ming-cheng-bu-neng-zhong-fu'))
        }
        const temp = cellValue.toLowerCase()
        if (EFormConstant.keys.indexOf(temp) !== -1) {
          return new Error(this.$t('m.eform.formDesign.label.zi-duan-ming-wei-bao-liu-zi'))
        }
      }
    }
    return {
      height: document.body.clientHeight - 53 - 55 - 150 - 52,
      height2: document.body.clientHeight - 53 - 55 - 150,
      record: null,
      noShowConfig: ['hidden', 'switch', 'editor', 'icon'],
      showType: EFormConstant.showType,
      colType: EFormConstant.colType,
      validRule: EFormConstant.validRule,
      isNullCheckAll:'N',//允许为空全选标记值
      validatorRules: {
        tableName: {rules: [{required: true, message: this.$t('m.eform.formDesign.label.qing-shu-ru-biao-ming-cheng')}, {validator: this.checkCode}]},
        tableDesc: {rules: [{required: true, message: this.$t('m.eform.formDesign.label.qing-shu-ru-biao-miao-shu')}]},
        dsCode: {
          initialValue: 'dataSourceDefault'
        },
        orderNum: {
          initialValue: 1 // TODO 默认值取数据库最大值+10
        },
      },
      disabledRules: {
        tableName: false,
        dsCode: false,
      },
      refKeys: ['actAppCol', 'actAppColShowConfig'],
      activeKey: 'actAppCol',
      // 表字段定义
      dataSource: [],
      validRules: {
        colCode: [
          {required: true, message: this.$t('m.eform.formDesign.label.zi-duan-ming-cheng-bu-neng-wei-kong')},
          {validator: colCodeValid},
        ],
        colName: [
          {required: true, message: this.$t('m.eform.formDesign.label.zi-duan-miao-shu-bu-neng-wei-kong')},
        ],
        colType: [
          {required: true, message: this.$t('m.eform.formDesign.label.zi-duan-lei-xing-bu-neng-wei-kong')},
        ],
        colLength: [
          {validator: colLengthValid},
        ],
        colPointLength: [
          {validator: colPointLengthValid},
        ],
      },
      initData: {
        colCode: '',
        colName: '',
        colType: 'varchar',
        colLength: 255,
        colPointLength: 0,
        isKey: 'N',
        isNull: 'Y',
        colDefaultVal: '',
        showType: 'input',
        showConfig: '',
        dataConfig: '',
        validRule: '',
        orderNum: 0,
        isDefault: 'N',
        isRequired: 'N'
      },
      labelCol2: {
        xs: {span: 24},
        sm: {span: 12}
      },
      wrapperCol2: {
        xs: {span: 24},
        sm: {span: 12}
      },
      url: {
        add: YchConstant.PREFIX_EFORM + '/manage/actAppTable/add',
        edit: YchConstant.PREFIX_EFORM + '/manage/actAppTable/edit',
        checkCode: YchConstant.PREFIX_EFORM + '/manage/actAppTable/checkCode',
        actAppCol: {
          list: YchConstant.PREFIX_EFORM + '/manage/actAppTable/queryActAppColByMainId'
        },
      }
    }
  },
  methods: {
    createDefaultRow(colCode, colName, colType, colLength, isKey, dataConfig) {
      let id = randomString(32)
      return {
        id: id,
        colCode: colCode,
        colName: colName,
        colType: colType,
        colLength: colLength,
        colPointLength: 0,
        isKey: isKey ? 'Y' : 'N',
        isNull: isKey ? 'N' : 'Y',
        colDefaultVal: '',
        showType: 'hidden',
        showConfig: '',
        dataConfig: dataConfig,
        validRule: '',
        orderNum: 0,
        isDefault: 'Y',
        isRequired: 'N'
      }
    },
    addBefore() {
      this.isNullCheckAll = 'N'
      const id = this.createDefaultRow('id', '主键', 'varchar', 36, true, '')
      const createBy = this.createDefaultRow('create_by', '创建人', 'varchar', 64, false, '{"type":"userCode","options":{}}')
      const createTime = this.createDefaultRow('create_time', '创建时间', 'date', 0, false, '{"type":"dateTime","options":{"format":"YYYY-MM-DD HH:mm:ss"}}')
      const updateBy = this.createDefaultRow('update_by', '更新人', 'varchar', 64, false, '{"type":"userCode","options":{}}')
      const updateTime = this.createDefaultRow('update_time', '更新时间', 'date', 0, false, '{"type":"dateTime","options":{"format":"YYYY-MM-DD HH:mm:ss"}}')
      const sysOrgCode = this.createDefaultRow('sys_org_code', '创建人部门', 'varchar', 64, false, '{"type":"deptCode","options":{}}')
      const dataStatus = this.createDefaultRow('data_status', '草稿状态', 'varchar', 36, false, '')
      const logicStatus = this.createDefaultRow('logic_status', '逻辑删除状态', 'varchar', 36, false, '')
      this.dataSource = [id, createBy, createTime, updateBy, updateTime, sysOrgCode,dataStatus, logicStatus]
    },
    editAfter() {
      // 启用排序功能
      this.rowDrop('xTable', (newIndex, oldIndex) => {
        this.afterRowDrop(newIndex, oldIndex, this.dataSource);
      })

      this.activeKey = this.refKeys[0]

      let fieldVal = this.lodash.pick(this.model, 'tableName', 'tableDesc', 'dsCode', 'orderNum')
      this.$nextTick(() => {
        this.form.setFieldsValue(fieldVal)
      })

      // 加载子表数据
      if (this.model.id) {
        let params = {id: this.model.id}
        this.spinning++
        getAction(this.url.actAppCol.list, params).then(res => {
          let {result} = res
          this.dataSource = result || []
        }).finally(() => {
          this.spinning--
        })
      }

      // 建表之后，禁止更改表名和数据源
      this.disabledRules.tableName = this.model.isSync && this.model.isSync !== '0';
      this.disabledRules.dsCode = this.model.isSync && this.model.isSync !== '0';
    },
    async beforeSave(formData) {
      formData.groupId = this.groupId
      const tableData = await this.getTableDataSource(this.$refs.xTable, this.dataSource);
      if (tableData === false) {
        // 返回空，终止保存动作
        this.activeKey = this.refKeys[0]
        return
      }
      this.resetOrderNum(this.dataSource)
      this.dataSource.forEach(item => {
        if (item.colCode === 'id') {
          item['orderNum'] = 0;
        } else if (item.colCode === 'create_by') {
          item['orderNum'] = 1001;
        } else if (item.colCode === 'create_time') {
          item['orderNum'] = 1002;
        } else if (item.colCode === 'update_by') {
          item['orderNum'] = 1003;
        } else if (item.colCode === 'update_time') {
          item['orderNum'] = 1004;
        } else if (item.colCode === 'sys_org_code') {
          item['orderNum'] = 1005;
        }else if (item.colCode === 'data_status') {
          item['orderNum'] = 1006;
        }else if (item.colCode === 'logic_status') {
          item['orderNum'] = 1007;
        }
      })
      formData.actAppColList = this.dataSource
      return formData;
    },
    afterClose() {
      this.dataSource = []
    },
    checkCode(rule, value, callback) {
      if (!value) {
        callback()
        return
      }
      let reg = new RegExp("[\\u4E00-\\u9FFF]+", "g");
      if (reg.test(value)) {
        callback(this.$t('m.eform.formDesign.label.biao-ming-cheng-bu-neng-bao-han-han-zi'))
        return
      }
      getAction(this.url.checkCode, {
        value: value,
        id: this.model.id
      }).then((res) => {
        res.success ? callback() : callback(res.message)
      })
    },
    showConfigButton(record) {
      this.record = record
      this.$refs.formShowConfigDialog.open(record.showConfig, record)
    },
    showConfigOk(json) {
      this.record['showConfig'] = json
    },
    saveToDataConfig(model, record) {
      this.$refs.dataConfigDialog.pasteDataConfig(model, record)
    },
    dataConfigButton(record) {
      this.record = record
      this.$refs.dataConfigDialog.open(record.dataConfig, record)
    },
    dataConfigOk(json) {
      this.record['dataConfig'] = json
    },
    formatterValidRule({cellValue}) {
      if (!cellValue) {
        return '';
      }
      let labels = cellValue.split(",").map(value => {
        let item = this.validRule.find(item => item.value === value)
        return item ? item.label : value
      })
      return labels.length > 0 ? labels.join(",") : ''
    },
    formatterColType({cellValue}) {
      if (!cellValue) {
        return '';
      }
      const option = this.colType.find(item => item.value === cellValue)
      return option ? option.label : ''
    },
    activeRowMethod({row, column}) {
      if (column.property === "colCode") {
        this.focusColCode({row, column})
      }
      if (row.isDefault === "Y") {
        this.$refs.xTable.clearActived()
        return false
      }
      if (column.property === "colLength" && !(row.colType === 'varchar' || row.colType === 'number')) {
        this.$refs.xTable.clearActived()
        return false
      }
      if (column.property === "colPointLength" && !(row.colType === 'number')) {
        this.$refs.xTable.clearActived()
        return false
      }
      return true
    },
    changeColType({row}) {
      let colPointLength = 0
      let colLength
      if (row.colType === 'number') {
        colLength = 10
      } else if (row.colType === 'varchar') {
        colLength = 255
      } else {
        colLength = 0
      }
      row["colLength"] = colLength
      row["colPointLength"] = colPointLength
    },
    focusColCode({row}) {
      if (row.colCode) {
        return
      }
      let colCode = "";
      if (row.colName) {
        colCode = pinyin.getCamelChars(row.colName)
        colCode = colCode.toLowerCase()
      }
      row['colCode'] = colCode
    },
    changeIsNull(row, event) {
      if (!event.checked) {
        row["isRequired"] = "Y"
      }
    },
    deleteRow() {
      const $table = this.$refs.xTable
      const selectRecords = $table.getCheckboxRecords()
      if (selectRecords.length === 0) {
        this.messageUtil.warning(this.$t('m.eform.formDesign.label.mei-you-xuan-zhong-shu-ju'))
        return
      }

      const defaultCol = selectRecords.filter(item => item.colCode === 'id' || item.colCode === 'create_by' || item.colCode === 'create_time' || item.colCode === 'update_by' || item.colCode === 'update_time' || item.colCode === 'sys_org_code' || item.colCode === 'data_status' || item.colCode === 'logic_status')
      if (defaultCol && defaultCol.length > 0) {
        this.messageUtil.warning(this.$t('m.eform.formDesign.label.mo-ren-zi-duan-bu-neng-shan-chu'))
        return
      }

      const ids = selectRecords.map(item => item.id)
      const data = [...this.dataSource]
      this.dataSource = data.filter(item => ids.indexOf(item.id) === -1)
    },
    async insertRow(tableId, dataSource, initData, activeCell) {
      const $table = this.$refs[tableId]
      let id = randomString(32)
      const record = {
        id: id,
        ...initData
      }
      let index = 0;
      for (let i = 0; i < dataSource.length; i++) {
        const item = dataSource[i]
        if (item.colCode === 'create_by'
          || item.colCode === 'create_time'
          || item.colCode === 'update_by'
          || item.colCode === 'update_time'
          || item.colCode === 'sys_org_code'
          || item.colCode === 'data_status'
          || item.colCode === 'logic_status'
        ) {
          index = i
          break
        }
      }
      dataSource.splice(index, 0, record)
      if (activeCell) {
        await $table.setActiveCell(record, activeCell)
      }
    },
    //允许空值全选
    changeAllIsNull(event){
      if (event.checked) {
        this.dataSource.forEach(item=>{
          if(item.isDefault!='Y'){
            item.isNull = 'Y'
          }

        })
      }else{
        this.dataSource.forEach(item=>{
          if(item.isDefault!='Y'){
            item.isNull = 'N'
            item.isRequired = 'Y'
          }
        })
      }
    },
    addSystemField(){
      this.$refs.selectSystemField.add(this.dataSource)
    },
    selectSystemFieldOk(systemFields){
      this.dataSource = [...this.dataSource,...systemFields]
    },
  }
}
</script>

<style lang="less" scoped>
</style>
